package com.GUI;

import com.GUI.CustomControls.*;
import com.DAO.DAO;
import com.Entity.Employee;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;

public class mainPanelCotroller implements Initializable, ChangeEmployeeListener {

    @FXML
    private Button addEmployee;
    @FXML
    private Button makeRanking;
    @FXML
    private TextField filterField;
    @FXML
    private TableView<EmployeeTableObject> table;
    @FXML
    private TableColumn<EmployeeTableObject, Boolean> chooseColumn;
    @FXML
    private TableColumn<EmployeeTableObject, String> nameColumn;
    @FXML
    private TableColumn<EmployeeTableObject, String> surnameColumn;
    @FXML
    private TableColumn editColumn;
    @FXML
    private TableColumn deleteColumn;

    private ObservableList<EmployeeTableObject> masterData = FXCollections.observableArrayList();
    private ObservableList<EmployeeTableObject> filteredData = FXCollections.observableArrayList();
    private DAO dao;
    private static mainPanelCotroller instance;

    public mainPanelCotroller() {
        dao = new DAO();
        List<Employee> data = dao.getAllEmployees();
        for (Employee emp : data) {
            EmployeeTableObject eto = new EmployeeTableObject(emp.getIdEmployee(), emp.getName(), emp.getSurname());
            masterData.add(eto);
        }

        filteredData.addAll(masterData);
        masterData.addListener(new ListChangeListener<EmployeeTableObject>() {
            @Override
            public void onChanged(ListChangeListener.Change<? extends EmployeeTableObject> change) {
                updateFilteredData();
            }
        });
    }

    private void updateFilteredData() {
        filteredData.clear();

        for (EmployeeTableObject p : masterData) {
            if (matchesFilter(p)) {
                filteredData.add(p);
            }
        }

        // Must re-sort table after items changed
        reapplyTableSortOrder();
    }

    private boolean matchesFilter(EmployeeTableObject emp) {
        String filterString = filterField.getText();
        if (filterString == null || filterString.isEmpty()) {
            return true;
        }
        String lowerCaseFilterString = filterString.toLowerCase();

        if (emp.getName().toLowerCase().indexOf(lowerCaseFilterString) != -1) {
            return true;
        }
        if (emp.getSurname().toLowerCase().indexOf(lowerCaseFilterString) != -1) {
            return true;
        }

        return false;
    }

    private void reapplyTableSortOrder() {
        ArrayList<TableColumn<EmployeeTableObject, ?>> sortOrder = new ArrayList<>(table.getSortOrder());
        table.getSortOrder().clear();
        table.getSortOrder().addAll(sortOrder);
        setButtonTableCell();
    }

    @FXML
    private void handleButtonAction(ActionEvent e) {
        Popup popup = new Popup();
        if(e.getSource()==addEmployee) {
            System.out.println("Dodaje pracownika");
            popup.createPopupEmployee();

        }
        if(e.getSource()==makeRanking) {
            System.out.println("Tworze ranking");
            
            List<Employee> employees = new ArrayList<>();
            for (EmployeeTableObject emp : table.getItems()) {
                if (emp.isChoose()) {
                    employees.add(dao.getEmployee(emp.getId()));
                    System.out.printf("%s %s", emp.getName(), emp.getSurname());
                    System.out.println();
                }
            }
            
            popup.createPopupRanking(employees);
        }
    }

    @FXML
    @Override
    public void initialize(URL url, ResourceBundle rb) {

        nameColumn.setCellValueFactory(new PropertyValueFactory<EmployeeTableObject, String>("name"));
        surnameColumn.setCellValueFactory(new PropertyValueFactory<EmployeeTableObject, String>("surname"));
        
        chooseColumn.setCellValueFactory(new PropertyValueFactory<EmployeeTableObject, Boolean>("choose"));
        chooseColumn.setCellFactory(CheckBoxTableCell.forTableColumn(chooseColumn));
        
        setButtonTableCell();
        table.setItems(filteredData);

        filterField.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable,
                    String oldValue, String newValue) {
                updateFilteredData();
            }
        });
        
        instance = this;
    }
    
    public void setButtonTableCell()
    {
        editColumn.setCellFactory(
                new Callback<TableColumn<EmployeeTableObject, String>, TableCell<EmployeeTableObject, String>>() {
 
            @Override
            public TableCell<EmployeeTableObject, String> call(TableColumn<EmployeeTableObject, String> p) {
                return new EditButtonTableCell();
            }
         
        });
        
        deleteColumn.setCellFactory(
                new Callback<TableColumn<EmployeeTableObject, String>, TableCell<EmployeeTableObject, String>>() {
 
            @Override
            public TableCell<EmployeeTableObject, String> call(TableColumn<EmployeeTableObject, String> p) {
                return new DeleteButtonTableCell();
            }
         
        });
    }
    
    @Override
    public void employeeChangedEvent() {
        masterData.clear();
        
        dao = new DAO();
        List<Employee> data = dao.getAllEmployees();
        for (Employee emp : data) {
            EmployeeTableObject eto = new EmployeeTableObject(emp.getIdEmployee(), emp.getName(), emp.getSurname());
            masterData.add(eto);
        }
        
        updateFilteredData();
    }
    
    public static mainPanelCotroller getInstance() {
        return instance;
    } 
}
